#ifndef PATCHCOREAI_H
#define PATCHCOREAI_H
#ifdef slots
#undef slots
#endif
#include <Python.h>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>
#define slots Q_SLOT

#include "aipostprocess.h"
#include "rknn_api.h"
#include "opencv2/core/mat.hpp"
#include "source/configmanager.h"
#include <QDir>
#include <QObject>
#include <QVariantMap>


namespace py = pybind11;

class PatchCoreAi : public QObject {
    Q_OBJECT
public:
    PatchCoreAi() ;
    ~PatchCoreAi() ;

    int initial();
    bool loadModel(const QString &modelPath);
    bool unloadModel();
    bool loadCoreSet();
    int detect(cv::Mat &Image, object_detect_result_list *od_results, float objThresh);
    float pred_score() {return pred_score_;};

    const QString model_Path = "master/models/PatchCore/";
    const QString coresetFile = "coreset.bin";
    const int coresetDim = 1536 ;//384;


    QVariantList imageInfoList; // imag{"istrain":true,"img":001.jpg]}
    bool canRun = false ;
    bool readyRun = false;
    float currentSchedule = 0 ;
    QVariantMap coreSetDetal = {
        {"name", ParamValue.ccnfigfileName()},
        {"size", 0},
        {"c", 0}  //这个不要显示
    };
    QVariantMap modelDetal = {
        {"name", "待"},
        {"size", 0},
        {"type", "FP16"},
        {"coreSet", 0}
    };
    cv::Mat outImage_;

    int pre_training();
    int load_training_data();
    int start_training();
    int continue_iteration();
    void quit_training();
    // int start_training() {
    //     int ret = model_instance.attr("start_training")().cast<int>();
    //     return ret;
    // }

    // int continue_iteration() {
    //     int ret = model_instance.attr("continue_iteration")().cast<int>();
    //     return ret;
    // }

    int getmodelDataSize() const {return modelDetal["size"].toInt();};
    int getimgInputSize() const {return input_size;};
    const char* getSDKversion() const{return version.api_version;};
    void addTrainImage(const cv::Mat img);
    void delTrainImage(int index);
    void clearTrainImage();

private:
    //交互变量
    //
    int imageIndex ;
    py::module pyTrain;
    py::object pyTrainClass;

    char* rknn_model_path;

    QDir modelBeloneDir;
    //rknn
    rknn_context ctx = 0;
    rknn_input_output_num ioNum;
    int modelDataSize;
    rknn_sdk_version version;
    unsigned char *modelData;
    int input_num ;
    rknn_tensor_mem *input_mems[2];
    rknn_tensor_mem *output_mems[2];
    rknn_tensor_attr inputAttrs[2];
    rknn_tensor_attr outputAttrs[2];
    int input_size = 224;
    cv::Mat image;
    float pred_score_;
};

// int testPybind11() {
//     try {
//         MyModel model;

//         // Initializing model
//         int ret = model.initial("coreset.npy");
//         if (ret != 0) {
//             std::cerr << "Initialization failed with error code: " << ret << std::endl;
//             return ret;
//         }

//         // Example image for inference
//         cv::Mat img = cv::imread("example.jpg");
//         if (img.empty()) {
//             std::cerr << "Could not open or find the image!" << std::endl;
//             return -1;
//         }

//         // Performing inference
//         py::object result = model.inference(img);
//         if (result.is_none()) {
//             std::cerr << "Inference failed." << std::endl;
//             return -1;
//         }

//         // Further processing based on result...
//         // ...

//         // Load training data
//         ret = model.load_training_data(img);
//         if (ret != 0) {
//             std::cerr << "Loading training data failed with error code: " << ret << std::endl;
//             return ret;
//         }

//         // Pre-training
//         ret = model.pre_training();
//         if (ret != 0) {
//             std::cerr << "Pre-training failed with error code: " << ret << std::endl;
//             return ret;
//         }

//         // Start training
//         ret = model.start_training();
//         if (ret != 0) {
//             std::cerr << "Start training failed with error code: " << ret << std::endl;
//             return ret;
//         }

//         // Continue iteration
//         ret = model.continue_iteration();
//         if (ret != 0) {
//             std::cerr << "Continue iteration failed with error code: " << ret << std::endl;
//             return ret;
//         }

//     } catch (const py::error_already_set& e) {
//         std::cerr << "Python error: " << e.what() << std::endl;
//     }

//     return 0;
// }

#endif // PATCHCOREAI_H
